package com.noble.glamour.ui.qiniu.edit;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.noble.glamour.R;
import com.noble.glamour.ui.qiniu.view.AudioMixSettingDialog;
import com.noble.glamour.ui.qiniu.view.TextSelectorPanel;
import com.noble.library.base.BaseAppCompatActivity;
import com.noble.library.log.PLogger;
import com.noble.library.log.PToast;
import com.noble.library.utils.ScreenUtils;
import com.qiniu.pili.droid.shortvideo.PLShortVideoEditor;
import com.qiniu.pili.droid.shortvideo.PLShortVideoUploader;
import com.qiniu.pili.droid.shortvideo.PLTextView;
import com.qiniu.pili.droid.shortvideo.PLUploadProgressListener;
import com.qiniu.pili.droid.shortvideo.PLUploadResultListener;
import com.qiniu.pili.droid.shortvideo.PLVideoEditSetting;
import com.qiniu.pili.droid.shortvideo.PLVideoSaveListener;
import com.qiniu.pili.droid.shortvideo.PLWatermarkSetting;
import com.qiniu.shortvideo.play.PLPlayMgr;
import com.qiniu.shortvideo.utils.GetPathFromUri;
import com.qiniu.shortvideo.utils.PLConstant;
import com.qiniu.shortvideo.utils.PLUtils;
import com.qiniu.shortvideo.view.CustomProgressDialog;
import com.qiniu.shortvideo.view.StrokedTextView;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * 短视频编辑页
 * Created by Su on 2017/11/13.
 */
public class PLEditActivity extends BaseAppCompatActivity implements PLVideoSaveListener, PLUploadResultListener, PLUploadProgressListener {
    private RecyclerView mFiltersList;
    private AudioMixSettingDialog mAudioMixSettingDialog;
    private ImageView mMuteButton;      // 开关本地录入音频
    private TextSelectorPanel mTextSelectorPanel; // 特效文字选择

    private String mSelectedFilter;
    private String mSelectedMV;
    private String mSelectedMask;

    private EditText mCurTextView;
    private boolean mIsTextViewMoved;

    private int mFgVolume = 100;
    private int mBgVolume = 100;
    private int mFgVolumeBeforeMute = 100;
    private long mAudioMixPosition = 0;
    private long mMixDuration = 5000; // ms
    private boolean mIsMuted = false;
    private boolean mIsMixAudio = false;
    private boolean mIsAudioMixDialogShown = false;
    private boolean mIsUseWatermark = true;         // 是否设置水印

    private PLVideoEditSetting setting;              // step1: 配置编辑参数
    private PLShortVideoEditor mShortVideoEditor;    // step2: 创建编辑对象
    private GLSurfaceView mPreviewView;              // 用于渲染视频编辑后的效果
    private PLWatermarkSetting mWatermarkSetting;    // 设置水印参数

    private TextView video_upload;  // 上传
    private ProgressBar mProgressBarDeterminate; // 上传进度条
    private boolean mIsUpload = false;
    private PLShortVideoUploader mVideoUploadManager;// 创建视频上传对象
    private CustomProgressDialog mProcessingDialog; // 文件保存进度条

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pl_short_edit);
        initView();
    }

    private void initView() {
        RelativeLayout header = (RelativeLayout) findViewById(R.id.video_header);
        header.setPadding(0, ScreenUtils.getStatusBarHeight(this), 0, 0);

        // 上传相关
        video_upload = (TextView) findViewById(R.id.video_upload);
        mProgressBarDeterminate = (ProgressBar) findViewById(R.id.progressBar);
        mProgressBarDeterminate.setMax(100);
        mVideoUploadManager = PLPlayMgr.getInstance().getPLShortVideoUploader(getApplicationContext());
        mVideoUploadManager.setUploadProgressListener(this);
        mVideoUploadManager.setUploadResultListener(this);

        mPreviewView = (GLSurfaceView) findViewById(R.id.preview);
        mFiltersList = (RecyclerView) findViewById(R.id.recycler_view);
        mTextSelectorPanel = (TextSelectorPanel) findViewById(R.id.text_selector_panel);
        mTextSelectorPanel.setOnTextClickedListener(new TextSelectorPanel.OnTextClickedListener() {
            @Override
            public void onTextClicked(StrokedTextView textView) {
                addText(textView);
            }
        });
        mTextSelectorPanel.setOnViewClosedListener(new TextSelectorPanel.OnViewClosedListener() {
            @Override
            public void onViewClosed() {
                mTextSelectorPanel.setVisibility(View.GONE);
            }
        });

        mPreviewView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mCurTextView != null && mCurTextView.getBackground() != null) {
                    mCurTextView.setBackgroundResource(0);
                    mCurTextView = null;
                }
            }
        });

        mProcessingDialog = new CustomProgressDialog(this);
        mProcessingDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                mShortVideoEditor.cancelSave();
            }
        });

        mMuteButton = (ImageView) findViewById(R.id.mute_button);
        mMuteButton.setImageResource(R.drawable.btn_unmute);

        mWatermarkSetting = new PLWatermarkSetting();
        mWatermarkSetting.setResourceId(R.drawable.water_mark);
        mWatermarkSetting.setPosition(0.01f, 0.01f);
        mWatermarkSetting.setAlpha(128);

        String path = getIntent().getStringExtra(PLConstant.VIDEO_PLAY_PATH);
        PLUtils.log("editing file: " + path);

        // 配置编辑参数
        setting = new PLVideoEditSetting();
        setting.setSourceFilepath(path);                    // 视频源文件路径
        setting.setDestFilepath(PLConstant.EDITED_FILE_PATH);   // 编辑后保存的目标路径
        setting.setKeepOriginFile(true);                    // 编辑保存后，是否保留源文件
        mShortVideoEditor = new PLShortVideoEditor(mPreviewView, setting);

        // 监听保存状态和结果
        mShortVideoEditor.setVideoSaveListener(this);
        mMixDuration = mShortVideoEditor.getDurationMs();
        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        mFiltersList.setLayoutManager(layoutManager);

        mAudioMixSettingDialog = new AudioMixSettingDialog(this);
        mAudioMixSettingDialog.setOnAudioVolumeChangedListener(mOnAudioVolumeChangedListener);
        mAudioMixSettingDialog.setOnPositionSelectedListener(mOnPositionSelectedListener);
    }

    private void setMixVolume() {
        // 设置原音（前景）和混音文件（背景）的音量[0-1.0f]
        mShortVideoEditor.setAudioMixVolume(mFgVolume / 100f, mBgVolume / 100f);
    }

    private void setMixAudioDuration() {
        if (mShortVideoEditor == null) {
            return;
        }

        int duration = mShortVideoEditor.getAudioMixFileDuration();
        mAudioMixSettingDialog.setMixMaxPosition(duration);
        PLUtils.log("duration = " + duration);
    }

    /**
     * 回退上一步编辑
     */
    public void onClickReset(View v) {
        mSelectedFilter = null;
        mSelectedMV = null;
        mSelectedMask = null;
        mShortVideoEditor.setBuiltinFilter(null);
        mShortVideoEditor.setMVEffect(null, null);
        mShortVideoEditor.setAudioMixFile(null);
        if (mCurTextView instanceof PLTextView)
            mShortVideoEditor.removeTextView((PLTextView) mCurTextView);
        mIsMixAudio = false;
        if (mIsAudioMixDialogShown) {
            mAudioMixPosition = 0;
            mAudioMixSettingDialog.clearMixAudio();
        }
    }

    /**
     * 添加背景混音
     */
    public void onClickMix(View v) {
        PLUtils.chooseAudioFile(this);
    }

    /**
     * 编辑背景音乐
     */
    public void onClickAudioMixSetting(View v) {
        if (mIsMixAudio) {
            mAudioMixSettingDialog.show();
            mIsAudioMixDialogShown = true;
            mAudioMixSettingDialog.setSrcVolumeProgress(mFgVolume);
            mAudioMixSettingDialog.setMixVolumeProgress(mBgVolume);
            setMixAudioDuration();
            mAudioMixSettingDialog.setMixPosition((int) mAudioMixPosition);
        } else {
            PToast.showShort("请先选择背景音乐文件！");
        }
    }

    /**
     * 静音本地录入音频
     */
    public void onClickMute(View v) {
        if (!mIsMuted) {
            mFgVolumeBeforeMute = mFgVolume;
            mFgVolume = 0;
            mShortVideoEditor.muteOriginAudio(true);
            mIsMuted = true;
            mMuteButton.setImageResource(R.drawable.btn_mute);
        } else {
            mFgVolume = mFgVolumeBeforeMute;
            mShortVideoEditor.muteOriginAudio(false);
            mIsMuted = false;
            mMuteButton.setImageResource(R.drawable.btn_unmute);
        }
    }

    /**
     * 添加文字
     */
    public void onClickTextSelect(View v) {
        mTextSelectorPanel.setVisibility(View.VISIBLE);
    }

    public void onClickClose(View v) {
        finish();
    }

    /**
     * 是否添加水印:  默认添加，不能更改
     */
    public void onClickToggleWatermark(View v) {
        mIsUseWatermark = !mIsUseWatermark;
        mShortVideoEditor.setWatermark(mIsUseWatermark ? mWatermarkSetting : null);
    }

    /**
     * 添加文字特效
     */
    public void addText(StrokedTextView selectText) {
        final StrokedTextView textView = new StrokedTextView(this);
        textView.setText("点击输入...");
        textView.setTextSize(20);
        textView.setTypeface(selectText.getTypeface());
        textView.setTextColor(selectText.getTextColors());
        textView.setShadowLayer(selectText.getShadowRadius(), selectText.getShadowDx(), selectText.getShadowDy(), selectText.getShadowColor());
        textView.setAlpha(selectText.getAlpha());
        textView.setStrokeWidth(selectText.getStrokeWidth());
        textView.setStrokeColor(selectText.getStrokeColor());

        // 添加文字特效
        mShortVideoEditor.addTextView(textView);

        if (mCurTextView != null) {
            mCurTextView.setBackgroundResource(0);
        }
        mCurTextView = textView;
        mCurTextView.setBackgroundResource(R.drawable.border_text_view);

        GestureDetector.SimpleOnGestureListener simpleOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                mShortVideoEditor.removeTextView(textView);  // 双击移除
                if (mCurTextView != null) {
                    mCurTextView = null;
                }
                return true;
            }

            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                if (mIsTextViewMoved) {
                    return true;
                }
                final EditText edit = new EditText(PLEditActivity.this);
                edit.setText(textView.getText());

                AlertDialog.Builder builder = new AlertDialog.Builder(PLEditActivity.this);
                builder.setView(edit);
                builder.setTitle("请输入文字");
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        textView.setHint(edit.getText());
                    }
                });
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });
                builder.show();

                return true;
            }
        };
        final GestureDetector gestureDetector = new GestureDetector(PLEditActivity.this, simpleOnGestureListener);

        textView.setOnTouchListener(new View.OnTouchListener() {
            private float lastTouchRawX;
            private float lastTouchRawY;
            private boolean scale;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }

                int action = event.getAction();
                float touchRawX = event.getRawX();
                float touchRawY = event.getRawY();
                float touchX = event.getX();
                float touchY = event.getY();

                if (action == MotionEvent.ACTION_DOWN) {
                    boolean xOK = touchX >= v.getWidth() * 3 / 4 && touchX <= v.getWidth();
                    boolean yOK = touchY >= v.getHeight() * 2 / 4 && touchY <= v.getHeight();
                    scale = xOK && yOK;

                    if (mCurTextView != null) {
                        mCurTextView.setBackgroundResource(0);
                    }
                    mCurTextView = textView;
                    mCurTextView.setBackgroundResource(R.drawable.border_text_view);
                }

                if (action == MotionEvent.ACTION_MOVE) {
                    float deltaRawX = touchRawX - lastTouchRawX;
                    float deltaRawY = touchRawY - lastTouchRawY;

                    if (scale) {
                        // rotate
                        float centerX = v.getX() + (float) v.getWidth() / 2;
                        float centerY = v.getY() + (float) v.getHeight() / 2;
                        double angle = Math.atan2(touchRawY - centerY, touchRawX - centerX) * 180 / Math.PI;
                        v.setRotation((float) angle - 45);

                        // scale
                        float xx = (touchRawX >= centerX ? deltaRawX : -deltaRawX);
                        float yy = (touchRawY >= centerY ? deltaRawY : -deltaRawY);
                        float sf = (v.getScaleX() + xx / v.getWidth() + v.getScaleY() + yy / v.getHeight()) / 2;
                        v.setScaleX(sf);
                        v.setScaleY(sf);
                    } else {
                        // translate
                        v.setTranslationX(v.getTranslationX() + deltaRawX);
                        v.setTranslationY(v.getTranslationY() + deltaRawY);
                    }
                    mIsTextViewMoved = true;
                }

                if (action == MotionEvent.ACTION_UP) {
                    mIsTextViewMoved = false;
                }

                lastTouchRawX = touchRawX;
                lastTouchRawY = touchRawY;
                return true;
            }
        });
        PToast.showShort("触摸文字右下角控制缩放与旋转，双击移除。");
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            String selectedFilepath = GetPathFromUri.getPath(this, data.getData());
            PLUtils.log("Select file: " + selectedFilepath);
            if (selectedFilepath != null && !"".equals(selectedFilepath)) {

                // 设置混音文件（本地音频文件）
                mShortVideoEditor.setAudioMixFile(selectedFilepath);

                // 设置混音文件（assets下的音频文件）
                // mShortVideoEditor.setAudioMixAsset();
                mIsMixAudio = true;
                mBgVolume = 100;
                setMixVolume();
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        // 预览效果：结束播放
        mShortVideoEditor.stopPlayback();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mShortVideoEditor.setBuiltinFilter(mSelectedFilter);

        mShortVideoEditor.setMVEffect(mSelectedMV, mSelectedMask);
        mShortVideoEditor.setWatermark(mIsUseWatermark ? mWatermarkSetting : null);

        // 预览效果：开始播放
        mShortVideoEditor.startPlayback();
        if (mIsMuted) {
            mFgVolume = 0;
            mShortVideoEditor.muteOriginAudio(true);
            mMuteButton.setImageResource(R.drawable.btn_mute);
        }
        setMixVolume();
    }

    /**
     * 保存编辑的视频
     */
    public void onSaveEdit(View v) {
        // 正在上传
        if (mIsUpload) {
            mVideoUploadManager.cancelUpload();
            mProgressBarDeterminate.setVisibility(View.INVISIBLE);
            video_upload.setText(R.string.upload);
            mIsUpload = false;
            return;
        }

        // 先执行保存工作，保存成功后在上传
        mProcessingDialog.show();
        mShortVideoEditor.save();  // 执行保存操作

        if (mCurTextView != null && mCurTextView.getBackground() != null) {
            mCurTextView.setBackgroundResource(0);
            mCurTextView = null;
        }
    }

    //  TODO 上传
    @Override
    public void onSaveVideoSuccess(String filePath) {
        PLUtils.log("save edit success filePath: " + filePath);
        mProcessingDialog.dismiss();
        doUpload(filePath);
    }

    @Override
    public void onSaveVideoFailed(int errorCode) {
        PLUtils.log("save edit failed errorCode:" + errorCode);
        mProcessingDialog.dismiss();
    }

    @Override
    public void onSaveVideoCanceled() {
        mProcessingDialog.dismiss();
    }

    @Override
    public void onProgressUpdate(float percentage) {
        mProcessingDialog.setProgress((int) (100 * percentage));
    }

    private AudioMixSettingDialog.OnAudioVolumeChangedListener mOnAudioVolumeChangedListener = new AudioMixSettingDialog.OnAudioVolumeChangedListener() {
        @Override
        public void onAudioVolumeChanged(int fgVolume, int bgVolume) {
            mFgVolume = fgVolume;
            mBgVolume = bgVolume;
            setMixVolume();
            mIsMuted = mFgVolume == 0;
            mMuteButton.setImageResource(mIsMuted ? R.drawable.btn_mute : R.drawable.btn_unmute);
        }
    };

    private AudioMixSettingDialog.OnPositionSelectedListener mOnPositionSelectedListener = new AudioMixSettingDialog.OnPositionSelectedListener() {
        @Override
        public void onPositionSelected(long position) {
            mAudioMixPosition = position;

            // 设置混音的起始和结束位置
            mShortVideoEditor.setAudioMixFileRange(position, position + mMixDuration);
        }
    };

    // ============================= 上传 =============================
    private void doUpload(final String videoPath) {
        if (mIsUpload) return;

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mVideoUploadManager.startUpload(videoPath, PLConstant.TOKEN);
                mProgressBarDeterminate.setVisibility(View.VISIBLE);
                video_upload.setText(R.string.cancel_upload);
                mIsUpload = true;
            }
        });
    }

    @Override
    public void onUploadProgress(String fileName, final double percent) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mProgressBarDeterminate.setProgress((int) (percent * 100));
                if (1.0 == percent) {
                    mProgressBarDeterminate.setVisibility(View.INVISIBLE);
                }
            }
        });
    }

    @Override
    public void onUploadVideoSuccess(JSONObject response) {
        try {
            String filePath = "http://" + PLConstant.DOMAIN + "/" + response.getString("key");
            PLogger.d("httpfilepath: " + filePath);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    resetUploadView();
                }
            });

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onUploadVideoFailed(int statusCode, String error) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                resetUploadView();
            }
        });
    }

    /**
     * 重置上传视图
     */
    public void resetUploadView() {
        mProgressBarDeterminate.setVisibility(View.INVISIBLE);
        video_upload.setText(R.string.upload);
        mIsUpload = false;
    }
}

